#ifndef __EVENTLOOP_HPP__
#define __EVENTLOOP_HPP__

#include "TcpConnection.hpp"
#include "Acceptor.hpp"

#include <header.h>

#include <memory>
#include <functional>
#include <vector>
#include <map>

using std::shared_ptr;
using std::function;
using std::vector;
using std::map;

namespace xww
{
    // class TcpConnection;
    using TcpConnectionPtr = shared_ptr<TcpConnection>;
    using TcpConnectionCallback = function<void(TcpConnectionPtr)>;

    // class Acceptor;

    class EventLoop
    {
        public:
            EventLoop(Acceptor &acceptor);
            ~EventLoop();

            void loop();// 事件循环

            void unloop();// 退出循环, 要与loop函数运行在不同的线程

            //设置三个函数对象
            //要表达完整的移动语义，就需要使用std::move
            void EsetAllCallbacks(TcpConnectionCallback &&cb1, 
                                  TcpConnectionCallback &&cb2,
                                  TcpConnectionCallback &&cb3)
            {
                _EonConnection = std::move(cb1);
                _EonMessage = std::move(cb2);
                _EonClose = std::move(cb3);
            }

        private:
            void waitEpollFd();// 等待epoll事件
            int createEpollFd();// 创建epoll文件描述符
            void addEpollReadEvent(int fd);// 添加读事件到epoll
            void delEpollReadEvent(int fd);// 从epoll中删除读事件

            void handleNewConnection();// 处理新连接
            void handleMessage(int fd);// 处理消息

        private:
            int _epfd; // epoll文件描述符
            bool _isLooping; // 是否在循环中
            Acceptor &_acceptor; // 引用Acceptor对象
            vector<struct epoll_event> _evtArr; // epoll事件数组
            map<int, TcpConnectionPtr> _conns; // 存储连接的映射
            TcpConnectionCallback _EonConnection;
            TcpConnectionCallback _EonMessage;
            TcpConnectionCallback _EonClose;


    };


}// end of namespace xww

#endif